package com.zlq.cn.service.ai;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.IdUtil;
import com.tencentcloudapi.aiart.v20221229.AiartClient;
import com.tencentcloudapi.aiart.v20221229.models.ImageToImageRequest;
import com.tencentcloudapi.aiart.v20221229.models.ImageToImageResponse;
import com.tencentcloudapi.aiart.v20221229.models.TextToImageRequest;
import com.tencentcloudapi.aiart.v20221229.models.TextToImageResponse;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.facefusion.v20220927.FacefusionClient;
import com.tencentcloudapi.facefusion.v20220927.models.FuseFaceRequest;
import com.tencentcloudapi.facefusion.v20220927.models.FuseFaceResponse;
import com.tencentcloudapi.facefusion.v20220927.models.MergeInfo;
import com.tencentcloudapi.fmu.v20191213.FmuClient;
import com.tencentcloudapi.fmu.v20191213.models.StyleImageProRequest;
import com.tencentcloudapi.fmu.v20191213.models.StyleImageProResponse;
import com.tencentcloudapi.ft.v20200304.FtClient;
import com.tencentcloudapi.ft.v20200304.models.*;
import com.tencentcloudapi.tiia.v20190529.TiiaClient;
import com.tencentcloudapi.tiia.v20190529.models.EnhanceImageRequest;
import com.tencentcloudapi.tiia.v20190529.models.EnhanceImageResponse;
import com.volcengine.service.visual.IVisualService;
import com.volcengine.service.visual.impl.VisualServiceImpl;
import com.zlq.cn.config.Config;
import com.zlq.cn.config.FinderConfiguration;
import com.zlq.cn.service.un.ConfigService;
import lombok.SneakyThrows;
import one.util.streamex.StreamEx;
import org.springframework.stereotype.Service;

@Service("tencentAiService")
public class TencentAiService {

    private final FtClient ftClient;

    private final TiiaClient tiiaClient;

    private final FmuClient fmuClient;

    private final FacefusionClient facefusionClient;

    private final AiartClient aiartClient;

    private final IVisualService visualService;

    private final AiCommonService aiCommonService;

    private final ConfigService configService;

    public TencentAiService(AiCommonService aiCommonService,
                            ConfigService configService,
                            FinderConfiguration configuration) {
        this.aiCommonService = aiCommonService;
        this.configService = configService;
        Credential cred = new Credential(configuration.getTencentSecretId(), configuration.getTencentSecretKey());
        // 实例化一个http选项，可选的，没有特殊需求可以跳过
        HttpProfile httpProfile = new HttpProfile();
        httpProfile.setEndpoint("ft.tencentcloudapi.com");
        // 实例化一个client选项，可选的，没有特殊需求可以跳过
        ClientProfile clientProfile = new ClientProfile();
        clientProfile.setHttpProfile(httpProfile);
        clientProfile.setDebug(true);
        // 实例化要请求产品的client对象,clientProfile是可选的
        ftClient = new FtClient(cred, "ap-guangzhou", clientProfile);

        // 实例化一个http选项，可选的，没有特殊需求可以跳过
        HttpProfile tiiaHttpProfile = new HttpProfile();
        tiiaHttpProfile.setEndpoint("tiia.ap-guangzhou.tencentcloudapi.com");
        // 实例化一个client选项，可选的，没有特殊需求可以跳过
        ClientProfile tiiaClientProfile = new ClientProfile();
        tiiaClientProfile.setHttpProfile(tiiaHttpProfile);
        tiiaClientProfile.setDebug(true);
        tiiaClient = new TiiaClient(cred, "ap-guangzhou", tiiaClientProfile);

        // 实例化一个http选项，可选的，没有特殊需求可以跳过
        HttpProfile fmuHttpProfile = new HttpProfile();
        fmuHttpProfile.setEndpoint("fmu.ap-guangzhou.tencentcloudapi.com");
        // 实例化一个client选项，可选的，没有特殊需求可以跳过
        ClientProfile fmuClientProfile = new ClientProfile();
        fmuClientProfile.setHttpProfile(fmuHttpProfile);
        fmuClientProfile.setDebug(true);
        fmuClient = new FmuClient(cred, "ap-guangzhou", fmuClientProfile);

        // 实例化一个http选项，可选的，没有特殊需求可以跳过
        HttpProfile facefusionHttpProfile = new HttpProfile();
        facefusionHttpProfile.setEndpoint("facefusion.ap-guangzhou.tencentcloudapi.com");
        // 实例化一个client选项，可选的，没有特殊需求可以跳过
        ClientProfile facefusionClientProfile = new ClientProfile();
        facefusionClientProfile.setHttpProfile(facefusionHttpProfile);
        facefusionClientProfile.setDebug(true);
        facefusionClient = new FacefusionClient(cred, "ap-guangzhou", facefusionClientProfile);

        // 实例化一个http选项，可选的，没有特殊需求可以跳过
        HttpProfile aiartHttpProfile = new HttpProfile();
        aiartHttpProfile.setEndpoint("aiart.tencentcloudapi.com");
        // 实例化一个client选项，可选的，没有特殊需求可以跳过
        ClientProfile aiartClientProfile = new ClientProfile();
        aiartClientProfile.setHttpProfile(aiartHttpProfile);
        aiartClientProfile.setDebug(true);
        aiartClient = new AiartClient(cred, "ap-guangzhou", aiartClientProfile);

        visualService = VisualServiceImpl.getInstance();
        visualService.setAccessKey(configuration.getVisualSecretId());
        visualService.setSecretKey(configuration.getVisualSecretKey());
    }

    @SneakyThrows
    public SwapGenderPicResponse swapGenderPic(SwapGenderPicRequest req) {
        aiCommonService.checkUserNum(Config.PROJECT_TENCENT_AI, "swapGenderPic", 10);
        SwapGenderPicResponse rep = ftClient.SwapGenderPic(req);
        rep.setResultUrl(aiCommonService.saveTencentAi(Config.PROJECT_TENCENT_AI, "swapGenderPic", req.getUrl(),
                configService.putObject("tencentAi", rep.getResultUrl())));
        return rep;
    }

    @SneakyThrows
    public ChangeAgePicResponse changeAgePic(ChangeAgePicRequest req) {
        aiCommonService.checkUserNum(Config.PROJECT_TENCENT_AI, "changeAgePic", 10);
        ChangeAgePicResponse rep = ftClient.ChangeAgePic(req);
        rep.setResultUrl(aiCommonService.saveTencentAi(Config.PROJECT_TENCENT_AI, "changeAgePic", req.getUrl(),
                configService.putObject("tencentAi", rep.getResultUrl())));
        return rep;
    }

    @SneakyThrows
    public FaceCartoonPicResponse faceCartoonPic(FaceCartoonPicRequest req) {
        aiCommonService.checkUserNum(Config.PROJECT_TENCENT_AI, "faceCartoonPic", 10);
        FaceCartoonPicResponse rep = ftClient.FaceCartoonPic(req);
        rep.setResultUrl(aiCommonService.saveTencentAi(Config.PROJECT_TENCENT_AI, "faceCartoonPic", req.getUrl(),
                configService.putObject("tencentAi", rep.getResultUrl())));
        return rep;
    }

    @SneakyThrows
    public MorphFaceResponse morphFace(MorphFaceRequest req) {
        aiCommonService.checkUserNum(Config.PROJECT_TENCENT_AI);
        return ftClient.MorphFace(req);
    }

    @SneakyThrows
    public QueryFaceMorphJobResponse queryFaceMorphJob(QueryFaceMorphJobRequest req) {
        aiCommonService.checkUserNum(Config.PROJECT_TENCENT_AI);
        return ftClient.QueryFaceMorphJob(req);
    }

    @SneakyThrows
    public CancelFaceMorphJobResponse cancelFaceMorphJob(CancelFaceMorphJobRequest req) {
        aiCommonService.checkUserNum(Config.PROJECT_TENCENT_AI);
        return ftClient.CancelFaceMorphJob(req);
    }

    @SneakyThrows
    public EnhanceImageResponse enhanceImage(EnhanceImageRequest req) {
        aiCommonService.checkUserNum(Config.PROJECT_TENCENT_AI);
        return tiiaClient.EnhanceImage(req);
    }

    @SneakyThrows
    public StyleImageProResponse styleImagePro(StyleImageProRequest req) {
        aiCommonService.checkUserNum(Config.PROJECT_TENCENT_AI, "styleImagePro", 10);
        StyleImageProResponse rep = fmuClient.StyleImagePro(req);
        rep.setResultUrl(aiCommonService.saveTencentAi(Config.PROJECT_TENCENT_AI, "styleImagePro", req.getUrl(),
                configService.putObject("tencentAi", rep.getResultUrl())));
        return rep;
    }

    @SneakyThrows
    public FuseFaceResponse fuseFace(FuseFaceRequest req) {
        aiCommonService.checkUserNum(Config.PROJECT_TENCENT_AI, "fuseFace", 10);
        FuseFaceResponse rep = facefusionClient.FuseFace(req);
        String url = StreamEx.of(req.getMergeInfos())
                .map(MergeInfo::getUrl)
                .joining(",");
        rep.setFusedImage(aiCommonService.saveTencentAi(Config.PROJECT_TENCENT_AI, "fuseFace", url,
                configService.putObject("tencentAi", rep.getFusedImage())));
        return rep;
    }

    @SneakyThrows
    public TextToImageResponse textToImage(TextToImageRequest req) {
        aiCommonService.checkUserNum(Config.PROJECT_TENCENT_AI, "textToImage", 5);
        TextToImageResponse rep = aiartClient.TextToImage(req);
        if ("url".equals(req.getRspImgType())) {
            rep.setResultImage(aiCommonService.saveTencentAi(Config.PROJECT_TENCENT_AI, "textToImage", req.getPrompt(),
                    configService.putObject("tencentAi/textToImage", req.getRspImgType())));
        } else {
            byte[] decode = Base64.decode(rep.getResultImage());
            rep.setResultImage(aiCommonService.saveTencentAi(Config.PROJECT_TENCENT_AI, "textToImage", req.getPrompt(),
                    configService.putObject("tencentAi/textToImage", createBeforeImage(), ".png", decode)));
        }
        return rep;
    }

    @SneakyThrows
    public ImageToImageResponse imageToImage(ImageToImageRequest req) {
        aiCommonService.checkUserNum(Config.PROJECT_TENCENT_AI, "imageToImage", 5);
        ImageToImageResponse rep = aiartClient.ImageToImage(req);
        if ("url".equals(req.getRspImgType())) {
            rep.setResultImage(aiCommonService.saveTencentAi(Config.PROJECT_TENCENT_AI, "imageToImage", req.getPrompt(),
                    configService.putObject("tencentAi/imageToImage", req.getRspImgType())));
        } else {
            byte[] decode = Base64.decode(rep.getResultImage());
            rep.setResultImage(aiCommonService.saveTencentAi(Config.PROJECT_TENCENT_AI, "imageToImage", req.getPrompt(),
                    configService.putObject("tencentAi/imageToImage", createBeforeImage(), ".png", decode)));
        }
        return rep;
    }

    public static String createBeforeImage() {
        return "http://ap-guangzhou.myqcloud.com/" + IdUtil.fastUUID() + ".png";
    }
}
